package com.example.ribbontest.service;

import com.example.ribbontest.domain.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "defaultUser")
    public User getUser()
    {
        throw new RuntimeException("getUser failed");
    }

    public User defaultUser(Throwable e)
    {
       if ("getUser failed".equals(e.getMessage()))
       {
           return new User("getUser failed","getUser failed");
       }
       return new User("user","password");
    }

    /**
     * cacheresult会把所有参数做为缓存的key
     * @param id
     * @return
     */
    @CacheResult
    @HystrixCommand
    public User getUserById(int id)
    {
        return restTemplate.getForObject("http://SPRING-BOOT-TEST/user/{1}",User.class,id);
    }

    @HystrixCommand
    public List<User> getUsers(List<Integer> ids)
    {
        return restTemplate.getForObject("http://SPRING-BOOT-TEST/users?ids={1}",List.class, StringUtils.join(ids,","));
    }


    /**
     * cacheresult指定生成key的方式
     * @param id
     * @return
     */
    @CacheResult(cacheKeyMethod = "getUserIdByCacheKey")
    @HystrixCommand
    public User getUserByIdGenKey(int id)
    {
        return restTemplate.getForObject("http://SPRING-BOOT-TEST/user/{1}",User.class,id);
    }

    private int getUserIdByCacheKey(int id)
    {
        return id;
    }

    /**
     * CacheRemove注解的使用
     * 更新缓存的方法，需要指定请求缓存的方法
     * @param user
     */
    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public User update(@CacheKey("id") User user)
    {
        return restTemplate.postForObject("http://SPRING-BOOT-TEST/users",user,User.class);
    }


    /**
     * 注解方式实现请求合并
     * @param id
     * @return
     */
    @HystrixCollapser(batchMethod = "findAll",scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,collapserProperties = {@HystrixProperty(name = "timerDelayInMilliseconds",value = "100")})
    public User find(Integer id)
    {
       return null;
    }

    @HystrixCommand
    public List<User> findAll(List<Integer> ids)
    {
        ParameterizedTypeReference<List<User>> responseType = new ParameterizedTypeReference<List<User>>(){};
        ResponseEntity<List<User>> user= restTemplate.exchange("http://SPRING-BOOT-TEST/users?ids={1}",
                HttpMethod.GET, null, responseType,StringUtils.join(ids,","));
        return user.getBody();
    }






}
